<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mermaid Editor</title>
    <style>
        body {
            font-family: 'Microsoft YaHei', 'WenQuanYi Zen Hei', 'SimHei', 'Arial', sans-serif;
            overflow: hidden;
        }

        #mermaid-container {
            overflow: hidden;
            position: relative;
            height: 100%;
            width: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: grab;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/dom-to-image-more@2.9.4/dist/dom-to-image-more.min.js"></script>
    <script>
        // Mermaid 配置初始化
        mermaid.initialize({ startOnLoad: true });

        // 绘图函数
        window.renderMermaid = function (value) {
            const element = document.getElementById('mermaid');
            try {
                // 清空上一个渲染内容
                element.innerHTML = '';

                // 动态插入用户输入的代码
                const mermaidDiv = document.createElement('div');
                mermaidDiv.className = 'mermaid';
                mermaidDiv.textContent = value;
                element.appendChild(mermaidDiv);

                // 渲染 Mermaid 代码
                mermaid.init(undefined, mermaidDiv);
            } catch (error) {
                console.error("Mermaid 渲染失败：", error);
                element.innerHTML = `<p style="color: red;">Mermaid 渲染失败，请检查代码语法！</p>`;
            }
        };

        document.addEventListener('DOMContentLoaded', () => {
            const defaultCode = document.getElementById('code').value;
            renderMermaid(defaultCode);
            initPanAndZoom();
        });

        function initPanAndZoom() {
            const container = document.getElementById('mermaid-container');
            const mermaidElement = document.getElementById('mermaid');
            let scale = 1;
            let panX = 0;
            let panY = 0;
            let isPanning = false;
            let startX = 0;
            let startY = 0;

            container.addEventListener('wheel', (event) => {
                event.preventDefault();
                const scaleAmount = 0.1;
                scale += event.deltaY > 0 ? -scaleAmount : scaleAmount;
                scale = Math.min(Math.max(.125, scale), 4);
                mermaidElement.style.transform = `scale(${scale}) translate(${panX}px, ${panY}px)`;
            });

            container.addEventListener('mousedown', (event) => {
                isPanning = true;
                startX = event.clientX - panX;
                startY = event.clientY - panY;
                container.style.cursor = 'grabbing';
            });

            container.addEventListener('mousemove', (event) => {
                if (!isPanning) return;
                panX = event.clientX - startX;
                panY = event.clientY - startY;
                mermaidElement.style.transform = `scale(${scale}) translate(${panX}px, ${panY}px)`;
            });

            container.addEventListener('mouseup', () => {
                isPanning = false;
                container.style.cursor = 'grab';
            });

            container.addEventListener('mouseleave', () => {
                isPanning = false;
                container.style.cursor = 'grab';
            });
        }

        // 定义 getDiagramType 函数在全局作用域
        function getDiagramType(code) {
            if (code.includes("flowchart")) return "flow chart";
            if (code.includes("sequenceDiagram")) return "sequence diagram";
            if (code.includes("classDiagram")) return "class diagram";
            if (code.includes("stateDiagram")) return "state diagram";
            if (code.includes("gantt")) return "gantt";
            if (code.includes("pie")) return "pie";
            if (code.includes("mindmap")) return "mind map";
            if (code.includes("erDiagram")) return "er diagram";
            return "Diagram";
        }

        function exportToPng() {
            const svgElement = document.querySelector("#mermaid svg");
            if (!svgElement) {
                alert("无法找到图表，请确认输入正确的 mermaid 数据！");
                return;
            }

            const wrapper = document.createElement("div");
            wrapper.appendChild(svgElement.cloneNode(true));

            const code = document.getElementById('code').value;
            const diagramType = getDiagramType(code);
            const fileName = `${diagramType}.png`;

            const scale = 8;
            const options = {
                width: svgElement.viewBox.baseVal.width * scale,
                height: svgElement.viewBox.baseVal.height * scale,
                style: {
                    transform: `scale(${scale})`,
                    transformOrigin: 'top left',
                },
            };

            domtoimage.toPng(wrapper, options).then((dataUrl) => {
                const link = document.createElement("a");
                link.download = fileName;
                link.href = dataUrl;
                link.click();
            }).catch((error) => {
                console.error("PNG 导出失败：", error);
                alert("导出失败，请检查图表并重试！");
            });
        }
    </script>
</head>
<body style="margin:0;display:flex;height:100vh;">
<!-- Mermaid 输入区 -->
<textarea id="code" style="width:25%;padding:10px;" oninput="renderMermaid(this.value)">graph TD;
    A-->B;
    </textarea>

<!-- Mermaid 图表输出区 -->
<div id="mermaid-container" style="width:75%;padding:10px;background-color:#f0f0f0;">
    <pre id="mermaid"></pre>
</div>

<!-- 导出按钮 -->
<button onclick="exportToPng()" style="position:absolute;right:20px;top:20px;">Export To PNG</button>

</body>
</html>
